﻿
#include "zyTreeView.h"

DarkMoonUI::zyTreeView::zyTreeView()
{
	SetMember(L"this", (LONG_PTR)this);
	m_obj->setWndProc(zyTreeView_WndProc);
	m_obj->setChildWndProc(zyTreeView_ChildWndProc);
	m_obj->setDestroy(zyTreeView_Destroy);
}
DarkMoonUI::zyTreeView::~zyTreeView()
{

}
void WINAPI DarkMoonUI::zyTreeView::zyTreeView_Destroy(zyObject* obj)
{
	zyTreeView* zyb = (zyTreeView*)obj->getPtrData(L"this");
	zyb->OnNCDestroy();
	zyCtrol::zyCtrol_Destroy(obj);
}
LRESULT WINAPI DarkMoonUI::zyTreeView::zyTreeView_ChildWndProc(zyObject* obj, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, BOOL* bHandle)
{
	if (message == WM_NOTIFY)
	{
		NMHDR* nm = reinterpret_cast<NMHDR*>(lParam);
		switch (nm->code) {
		case TVN_SELCHANGEDW: case TVN_SELCHANGEDA:
		{
			TRegEvent* evtPtr = reinterpret_cast<TRegEvent*>(obj->getRegEvent(L"OnSelChange"));
			if (evtPtr != nullptr) {
				NMTREEVIEW* nmTV = reinterpret_cast<NMTREEVIEW*>(lParam);
				evtPtr->handler<LRESULT>(nm->hwndFrom, nmTV->itemNew.hItem, nmTV->action);
			}
			break;
		}case NM_DBLCLK:
		{
			TRegEvent* evtPtr = reinterpret_cast<TRegEvent*>(obj->getRegEvent(L"OnDBClick"));
			if (evtPtr != nullptr) {
				LRESULT ret = evtPtr->handler<LRESULT>(nm->hwndFrom);
				*bHandle = TRUE;
				return ret;
			}
			break;
		}case TVN_BEGINLABELEDITW: case TVN_BEGINLABELEDITA:
		{
			//EditSubClass (nm.hwndFrom);
			TRegEvent* evtPtr = reinterpret_cast<TRegEvent*>(obj->getRegEvent(L"OnBeginEdit"));
			if (evtPtr != nullptr) {
				NMTVDISPINFO* nmtvdi = reinterpret_cast<NMTVDISPINFO*>(lParam);
				LRESULT ret = evtPtr->handler<LRESULT>(nm->hwndFrom, nmtvdi->item.hItem, nmtvdi->item.pszText);
				*bHandle = TRUE;
				return ret;
			}
			break;
		}case TVN_ENDLABELEDITW: case TVN_ENDLABELEDITA:
		{
			TRegEvent* evtPtr = reinterpret_cast<TRegEvent*>(obj->getRegEvent(L"OnEndEdit"));
			if (evtPtr != nullptr) {
				NMTVDISPINFO* nmtvdi = reinterpret_cast<NMTVDISPINFO*>(lParam);
				LRESULT ret = evtPtr->handler<LRESULT>(nm->hwndFrom, nmtvdi->item.hItem, nmtvdi->item.pszText);
				*bHandle = TRUE;
				return ret = 0 ? 1 : 0;
			}
			else {
				*bHandle = TRUE;
				return 1;
			}
			break;
		}case TVN_ITEMEXPANDINGW: case TVN_ITEMEXPANDINGA:
		{
			NMTREEVIEW* nmTV = reinterpret_cast<NMTREEVIEW*>(lParam);
			if ((nmTV->action & TVE_EXPAND) == TVE_EXPAND) {
				TRegEvent* evtPtr = reinterpret_cast<TRegEvent*>(obj->getRegEvent(L"OnItemExpand"));
				if (evtPtr != nullptr) {
					LRESULT ret = evtPtr->handler<LRESULT>(nm->hwndFrom, nmTV->itemNew.hItem);
					*bHandle = TRUE;
					return ret;
				}
			}
			else if ((nmTV->action & TVE_COLLAPSE) == TVE_COLLAPSE) {
				TRegEvent* evtPtr = reinterpret_cast<TRegEvent*>(obj->getRegEvent(L"OnItemCollapse"));
				if (evtPtr != nullptr) {
					LRESULT ret = evtPtr->handler<LRESULT>(nm->hwndFrom, nmTV->itemNew.hItem);
					*bHandle = TRUE;
					return ret;
				}
			}
			break;
		}case NM_RCLICK:
		{
			POINT pt = { 0 };
			GetCursorPos(&pt);
			ScreenToClient(nm->hwndFrom, &pt);
			TVHITTESTINFO tvhti = { 0 };
			tvhti.pt.x = pt.x;
			tvhti.pt.y = pt.y;
			TRegEvent* evtPtr = reinterpret_cast<TRegEvent*>(obj->getRegEvent(L"OnRButtonUp"));
			if (evtPtr != nullptr) {
				zyTreeView* p = (zyTreeView*)obj->getPtrData(L"this");
				LRESULT ret = evtPtr->handler<LRESULT>(nm->hwndFrom, pt.x, pt.y,p->GetFunKeyState());
				*bHandle = TRUE;
				return ret;
			}
			INT_PTR hItem = SendMessage(nm->hwndFrom, TVM_HITTEST, 0, (LPARAM)&tvhti);
			if ((tvhti.flags & TVHT_ONITEM) != 0) {
				TRegEvent* evtPtr = reinterpret_cast<TRegEvent*>(obj->getRegEvent(L"OnRClick"));
				if (evtPtr != nullptr) {
					LRESULT ret = evtPtr->handler<LRESULT>(nm->hwndFrom, hItem);
					*bHandle = TRUE;
					return ret;
				}
			}
			else if (hItem != 0)
				SendMessage(nm->hwndFrom, TVM_SELECTITEM, TVGN_CARET, hItem);
			return 0;
			break;
		}case NM_CLICK:
		{
			POINT pt = { 0 };
			GetCursorPos(&pt);
			ScreenToClient(nm->hwndFrom, &pt);
			TVHITTESTINFO tvhti = { 0 };
			tvhti.pt.x = pt.x;
			tvhti.pt.y = pt.y;
			INT_PTR hItem = SendMessage(nm->hwndFrom, TVM_HITTEST, 0, (LPARAM)&tvhti);
			if ((tvhti.flags & TVHT_ONITEM) != 0) {
				TRegEvent* evtPtr = reinterpret_cast<TRegEvent*>(obj->getRegEvent(L"OnClick"));
				if (evtPtr != nullptr) {
					LRESULT ret = evtPtr->handler<LRESULT>(nm->hwndFrom, hItem);
					*bHandle = TRUE;
					return ret;
				}
			}
			if ((tvhti.flags & TVHT_ONITEMSTATEICON) == TVHT_ONITEMSTATEICON) {
				TRegEvent* evtPtr = reinterpret_cast<TRegEvent*>(obj->getRegEvent(L"OnClick"));
				if (evtPtr != nullptr) {
					TVITEMEX item = { 0 };
					item.mask = TVIF_STATE;
					item.hItem = (HTREEITEM)hItem;
					item.stateMask = TVIS_STATEIMAGEMASK;
					SendMessage(nm->hwndFrom, TVM_GETITEMW, 0, (LPARAM)&item);
					int oldState = ((item.state & TVIS_STATEIMAGEMASK) >> 12) - 1;
					evtPtr->handler<LRESULT>(nm->hwndFrom, hItem, oldState = 0 ? 1 : 0);
				}
				SendMessage(nm->hwndFrom, TVM_SELECTITEM, TVGN_CARET, hItem);
			}
			break;
		}
		}
	}
	return zyCtrol::zyCtrol_ChildWndProc(obj, hWnd, message, wParam, lParam, bHandle);
}
LRESULT WINAPI DarkMoonUI::zyTreeView::zyTreeView_WndProc(zyObject* obj, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL* bHandle)
{
	if (uMsg == WM_NCDESTROY) {
		zyTreeView* zyb = (zyTreeView*)obj->getPtrData(L"this");
		zyb->OnNCDestroy();
	}
	return zyCtrol::zyCtrol_WndProc(obj, hWnd, uMsg, wParam, lParam, bHandle);
}
void DarkMoonUI::zyTreeView::OnNCDestroy() {
	resObject* pImageList = (resObject*)GetMember(L"pImageListNormal");
	if (pImageList != nullptr) {
		//IUnknown_Release (pImageList);
		pImageList->release();
		SetMember(L"pImageListNormal", 0);
	}
	pImageList = (resObject*)GetMember(L"pImageListState");
	if (pImageList != nullptr) {
		//IUnknown_Release (pImageList);
		pImageList->release();
		SetMember(L"pImageListState", 0);
	}
	zyEditBox* pEdit = (zyEditBox*)GetMember(L"pEdit");
	if (pEdit != nullptr) {
		//IUnknown_Release (pEdit);
		pEdit->getObject()->release();
		delete pEdit;
		SetMember(L"pEdit", 0);
	}
}
BOOL DarkMoonUI::zyTreeView::创建(HWND 参数_父窗口, const std::wstring& 参数_标题, POINT 参数_位置, POINT 参数_尺寸, int 参数_ID, int 参数_窗口风格, int 参数_扩展风格)
{
	if (参数_ID == NULL)
		参数_ID = 黑月默认ID();
	if (参数_窗口风格 == 0)
		参数_窗口风格 = WS_VSCROLL | WS_HSCROLL;
	if (参数_扩展风格 == 0)
		参数_扩展风格 = WS_EX_CLIENTEDGE;
	bool b = _CreateCtrol(参数_父窗口, 参数_标题, 参数_位置, 参数_尺寸, 参数_ID, 参数_窗口风格, 参数_扩展风格, L"SysTreeView32");
	if (b) {
		发送消息(TVM_SETITEMHEIGHT, 16, 0);//设置BUTTON结构大小
		发送消息(TVM_SETEXTENDEDSTYLE, TVS_EX_DOUBLEBUFFER, TVS_EX_DOUBLEBUFFER);
	}
	return b;
}

BOOL DarkMoonUI::zyTreeView::创建(zyWindow& 参数_父窗口, const std::wstring& 参数_标题, POINT 参数_位置, POINT 参数_尺寸, int 参数_ID, int 参数_窗口风格, int 参数_扩展风格)
{
	if (参数_ID == NULL)
		参数_ID = 黑月默认ID();
	if(参数_窗口风格 == 0)
		参数_窗口风格= WS_VSCROLL | WS_HSCROLL;
	if(参数_扩展风格 ==0)
		参数_扩展风格 = WS_EX_CLIENTEDGE;
	bool b = _CreateCtrol(参数_父窗口.getHwnd(), 参数_标题, 参数_位置, 参数_尺寸, 参数_ID, 参数_窗口风格, 参数_扩展风格, L"SysTreeView32");
	if (b) {
		发送消息(TVM_SETITEMHEIGHT, 16, 0);
		发送消息(TVM_SETEXTENDEDSTYLE, TVS_EX_DOUBLEBUFFER, TVS_EX_DOUBLEBUFFER);
	}
	return b;
}
HTREEITEM DarkMoonUI::zyTreeView::加入项目(HTREEITEM 参数_父项目句柄, const std::wstring& 参数_项目文本, int 参数_图片索引, int 参数_选择图片索引, INT_PTR 参数_项目数值, int 参数_加入方式) {
	TVINSERTSTRUCT TVIS = {0};
	HTREEITEM hInsertAfter = NULL;
	if (参数_加入方式 > 4 || 参数_加入方式 < 1)
		参数_加入方式 = 树型框插入项目_尾部;
	// 设置插入位置  
	switch (参数_加入方式) {
	case 1: hInsertAfter = TVI_ROOT; break;
	case 2: hInsertAfter = TVI_FIRST; break;
	case 3: hInsertAfter = TVI_LAST; break;
	case 4: hInsertAfter = TVI_SORT; break;
	}
	TVIS.item.mask = TVIF_TEXT | TVIF_PARAM;
	if (参数_图片索引 != -1) {
		TVIS.item.mask = TVIS.item.mask | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
		TVIS.item.iImage = 参数_图片索引;
		TVIS.item.iSelectedImage = (参数_选择图片索引 != -1) ? 参数_选择图片索引 : 参数_图片索引;
	}
	else {
		TVIS.item.iImage = -1;
		TVIS.item.iSelectedImage = -1;
	}
	if (参数_选择图片索引 != -1)
		TVIS.item.iSelectedImage = 参数_选择图片索引;
	TVIS.hParent = 参数_父项目句柄;
	TVIS.hInsertAfter = hInsertAfter;
	TVIS.item.pszText = (LPWSTR)参数_项目文本.c_str();
	TVIS.item.cchTextMax = (int)参数_项目文本.size();
	TVIS.item.lParam = 参数_项目数值;
	return (HTREEITEM)SendMessage (getHwnd(), TVM_INSERTITEM, 0, (LPARAM)&TVIS);
}
void DarkMoonUI::zyTreeView::扩展(HTREEITEM 参数_项目句柄) {
	sendMsg(TVM_EXPAND, TVE_EXPAND, (LPARAM)参数_项目句柄);
}
void DarkMoonUI::zyTreeView::收缩(HTREEITEM 参数_项目句柄) {
	sendMsg(TVM_EXPAND, TVE_COLLAPSE, (LPARAM)参数_项目句柄);
}
HTREEITEM DarkMoonUI::zyTreeView::插入项目(HTREEITEM 参数_父项目句柄, HTREEITEM 参数_项目句柄, const std::wstring& 参数_项目文本, int 参数_图片索引, int 参数_选择图片索引, INT_PTR 参数_项目数值) {//将一个项目加入到树型框中，成功返回加入后该项目句柄，失败返回 0。
	TVINSERTSTRUCT TVIS;
	TVIS.item.mask = TVIF_TEXT | TVIF_PARAM;
	if (参数_图片索引 == -1) {
		TVIS.item.mask = TVIS.item.mask | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
		TVIS.item.iImage = 参数_图片索引;
		TVIS.item.iSelectedImage = 参数_图片索引;
	}
	else {
		TVIS.item.iImage = -1;
		TVIS.item.iSelectedImage = -1;
	}
	if (参数_选择图片索引 == -1) {
		TVIS.item.iSelectedImage = 参数_选择图片索引;
	}
	TVIS.hParent = 参数_父项目句柄;
	TVIS.hInsertAfter = 参数_项目句柄;
	TVIS.item.pszText = (LPWSTR)参数_项目文本.c_str();
	TVIS.item.cchTextMax = (int)参数_项目文本.size();
	TVIS.item.lParam = 参数_项目数值;
	HTREEITEM hItem = (HTREEITEM)sendMsg(TVM_INSERTITEMW, 0, (LPARAM)&TVIS);
	return hItem;
}
bool DarkMoonUI::zyTreeView::绑定(HWND 参数_父窗口, int 参数_资源ID, bool 参数_使用默认字体) {//成功返回真，失败返回假。
	HWND hwnd = GetDlgItem(参数_父窗口, 参数_资源ID);
	if (hwnd != 0) {
		SendMessage(hwnd, TVM_SETEXTENDEDSTYLE, TVS_EX_DOUBLEBUFFER, TVS_EX_DOUBLEBUFFER);
		if (参数_使用默认字体) {
			SendMessage(hwnd, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), 0);
		}
	}
	return _BindWindow(hwnd);
}
bool DarkMoonUI::zyTreeView::绑定窗口句柄(HWND 参数_窗口句柄) {
	if (IsWindow(参数_窗口句柄) != 0) {
		SendMessage(参数_窗口句柄, TVM_SETEXTENDEDSTYLE, TVS_EX_DOUBLEBUFFER, TVS_EX_DOUBLEBUFFER);
	}
	return _BindWindow(参数_窗口句柄);
}
void DarkMoonUI::zyTreeView::枚举项目句柄(std::vector<HTREEITEM>& 参数_项目句柄数组) {//列举出树型框所有项目句柄。
	bool 局部_完成=false;
	int 局部_计次 = 0;
	参数_项目句柄数组.resize((int)sendMsg(TVM_GETCOUNT, 0, 0));
	HTREEITEM 局部_子项目 = (HTREEITEM)sendMsg(TVM_GETNEXTITEM, TVGN_ROOT, 0); // 取第一个根项目;
	while (局部_子项目 != 0) {
		局部_计次 = 局部_计次 + 1;
		参数_项目句柄数组[局部_计次 - 1] = 局部_子项目;
		INT_PTR 局部_数值 = (INT_PTR)局部_子项目;
		局部_子项目 = (HTREEITEM)sendMsg(TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)局部_子项目);  // 取第一个子项目;
		if (局部_子项目 == 0) { // 找不到子项目，就找兄弟项目{
			局部_子项目 = (HTREEITEM)sendMsg(TVM_GETNEXTITEM, TVGN_NEXT, 局部_数值);  // 取下一个兄弟项目;
			while (局部_子项目 == 0) {  // 找不到兄弟项目，就返回到上一级;
				INT_PTR 局部_父项目 = sendMsg(TVM_GETNEXTITEM, TVGN_PARENT, 局部_数值);  // 取父项目;
				if (局部_父项目 == 0) {
					局部_完成 = true;
					break;
				}
				局部_数值 = 局部_父项目;
				局部_子项目 = (HTREEITEM)sendMsg(TVM_GETNEXTITEM, TVGN_NEXT, 局部_数值);  // 取父的兄弟;
			}
		}
		if (局部_完成 == true) {
			break;
		}
	}
}
int DarkMoonUI::zyTreeView::取缩进层次(HTREEITEM 参数_项目句柄) {//返回指定项目所处缩进层次，层次值从1开始。如果未找到指定项目，返回 0 。
	int 局部_层次 = 1;
	HTREEITEM 局部_父项目 = (HTREEITEM)sendMsg(TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)参数_项目句柄);
	while (局部_父项目 != 0) {
		局部_层次 = 局部_层次 + 1;
		局部_父项目 = (HTREEITEM)sendMsg(TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)局部_父项目);
	}
	return 局部_层次;
}
std::wstring DarkMoonUI::zyTreeView::取项目文本(HTREEITEM 参数_项目句柄) {//返回指定项目的文本。如果该项目不存在，将返回{0,0}。
	std::wstring pszText;
	TVITEMEX item = { 0 };
	pszText.reserve(520);
	item.mask = TVIF_TEXT;
	item.hItem = 参数_项目句柄;
	item.pszText = (LPWSTR)pszText.c_str();
	item.cchTextMax = 260;
	if (sendMsg(TVM_GETITEMW, 0, (LPARAM)&item) == 0) {
		return L"";
	}
	return pszText;
}
int DarkMoonUI::zyTreeView::取图片(HTREEITEM 参数_项目句柄) {//返回指定项目的图片索引。如果该项目不存在，将返回 -1 。
	TVITEMEX item = { 0 };
	item.mask = TVIF_IMAGE;
	item.hItem = 参数_项目句柄;
	sendMsg(TVM_GETITEMW, 0, (LPARAM)&item);
	return item.iImage;
}
int DarkMoonUI::zyTreeView::取状态图片(HTREEITEM 参数_项目句柄) {//返回状态图片索引
	TVITEMEX item = { 0 };
	item.mask = TVIF_STATE;
	item.stateMask = TVIS_STATEIMAGEMASK;
	item.hItem = 参数_项目句柄;
	sendMsg(TVM_GETITEMW, 0, (LPARAM)&item);
	return  (item.state >> 12) - 1;
}
int DarkMoonUI::zyTreeView::取选择图片(HTREEITEM 参数_项目句柄) {//返回指定项目被选中后的图片索引。如果该项目不存在，将返回 -1 。
	TVITEMEX item = {0};
	item.mask = TVIF_SELECTEDIMAGE;
	item.hItem = 参数_项目句柄;
	if (sendMsg(TVM_GETITEMW, 0, (LPARAM)&item) == 0) {
		return -1;
	}
	return item.iSelectedImage;
}
INT_PTR DarkMoonUI::zyTreeView::取项目数值(HTREEITEM 参数_项目句柄) {//返回与指定项目相关联的数值。如果该项目不存在，将返回 0 。
	TVITEMEX item = { 0 };
	item.mask = TVIF_PARAM;
	item.hItem = 参数_项目句柄;
	sendMsg(TVM_GETITEMW, 0, (LPARAM)&item);
	return item.lParam;
}
bool DarkMoonUI::zyTreeView::置项目文本(HTREEITEM 参数_项目句柄, const std::wstring& 参数_欲置入的项目文本) {//设置指定项目的文本。成功返回真，失败返回假。
	TVITEMEX item = { 0 };
	item.mask = TVIF_TEXT;
	item.hItem = 参数_项目句柄;
	item.pszText = (LPWSTR)参数_欲置入的项目文本.c_str();
	item.cchTextMax = (int)参数_欲置入的项目文本.size();
	return sendMsg(TVM_SETITEMW, 0, (LPARAM)&item) != 0;
}
bool DarkMoonUI::zyTreeView::置图片(HTREEITEM 参数_项目句柄, int 参数_图片索引) {//设置在指定项目首部所显示图片的索引。成功返回真，失败返回假。
	TVITEMEX item = { 0 };
	item.mask = TVIF_IMAGE;
	item.hItem = 参数_项目句柄;
	item.iImage = 参数_图片索引;
	return sendMsg(TVM_SETITEMW, 0, (LPARAM)&item) != 0;
}
bool DarkMoonUI::zyTreeView::置状态图片(HTREEITEM 参数_项目句柄, int 参数_图片索引) {//返回状态图片索引
	TVITEMEX item = { 0 };
	item.mask = TVIF_STATE;
	item.stateMask = TVIS_STATEIMAGEMASK;
	item.state = (参数_图片索引 << 12) + 1;
	item.hItem = 参数_项目句柄;
	return sendMsg(TVM_GETITEMW, 0, (LPARAM)&item) != 0;
}
bool DarkMoonUI::zyTreeView::置选择图片(HTREEITEM 参数_项目句柄, int 参数_图片索引) {//置指定项目被选中后所显示图片的索引。成功返回真，失败返回假。
	TVITEMEX item = { 0 };
	item.mask = TVIF_SELECTEDIMAGE;
	item.hItem = 参数_项目句柄;
	item.iSelectedImage = 参数_图片索引;
	return sendMsg(TVM_SETITEMW, 0, (LPARAM)&item) != 0;
}
bool DarkMoonUI::zyTreeView::置项目数值(HTREEITEM 参数_项目句柄, INT_PTR 参数_欲置入的项目数值) {//设置与指定项目相关联的数值。成功返回真，失败返回假。
	TVITEMEX item = { 0 };
	item.mask = TVIF_PARAM;
	item.hItem = 参数_项目句柄;
	item.lParam = 参数_欲置入的项目数值;
	return sendMsg(TVM_SETITEMW, 0, (LPARAM)&item) != 0;
}
void DarkMoonUI::zyTreeView::保证显示(HTREEITEM 参数_项目句柄) {//确保指定项目能够显示出来，如果不能显示，则自动滚动并显示该项目。
	sendMsg(TVM_ENSUREVISIBLE, 0, (LPARAM)参数_项目句柄);
}
TVITEMEX DarkMoonUI::zyTreeView::取项目数据(HTREEITEM 参数_项目句柄) {
    if (参数_项目句柄 == NULL) {
        // 处理无效句柄的情况
        TVITEMEX item = {0};
        return item;
    }

    std::vector<WCHAR> pszText(260);
    TVITEMEX item = {0};
    HTREEITEM parentItem = (HTREEITEM)sendMsg(TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)参数_项目句柄);

    item.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE | TVIF_PARAM;
    item.hItem = 参数_项目句柄;
    item.pszText = pszText.data();
    item.cchTextMax = static_cast<int>(pszText.size());

    if (sendMsg(TVM_GETITEMW, 0, (LPARAM)&item) == 0) {
        // 获取项目信息失败，返回空结构
        TVITEMEX emptyItem = {0};
        return emptyItem;
    }

    // 如果需要获取父项目的更多信息，可以在这里继续处理
    // 例如：
    // if (parentItem != NULL) {
    //     // 获取父项目的信息
    // }

    return item;
}
RECT DarkMoonUI::zyTreeView::取项目矩形(HTREEITEM 参数_项目句柄, bool 参数_是否只包含标题) {
	RECT rc = {0};
	*(HTREEITEM*)&rc = 参数_项目句柄;
	sendMsg(TVM_GETITEMRECT, 参数_是否只包含标题 ? 1 : 0, (LPARAM)&rc);
	return rc;
}
bool DarkMoonUI::zyTreeView::是否有子项目(HTREEITEM 参数_项目句柄) {//如果指定项目存在子项目，返回真，否则返回假。如果本命令返回真，意味着指定项目的下一项即为此项目的第一个子项目。
	TVITEMEX item = { 0 };
	item.mask = TVIF_CHILDREN;
	item.hItem = 参数_项目句柄;
	sendMsg(TVM_GETITEMW, 0, (LPARAM)&item);
	return item.cChildren != 0;
}
bool DarkMoonUI::zyTreeView::是否已扩展(HTREEITEM 参数_项目句柄) {//如果树型框中的指定项目具有子项目并已扩展显示，返回真，否则返回假。
	int 局部_状态 = (int)sendMsg(TVM_GETITEMSTATE, (WPARAM)参数_项目句柄, 0);
	return (局部_状态 & TVIS_EXPANDED) == TVIS_EXPANDED;
}
bool DarkMoonUI::zyTreeView::加粗(HTREEITEM 参数_项目句柄) {
	TVITEMEX item = { 0 };
	item.mask = TVIF_STATE;
	item.hItem = 参数_项目句柄;
	item.state = TVIS_BOLD;
	item.stateMask = TVIS_BOLD;
	return sendMsg(TVM_SETITEMW, 0, (LPARAM)&item) != 0;
}
bool DarkMoonUI::zyTreeView::取消加粗(HTREEITEM 参数_项目句柄) {
	TVITEMEX item = { 0 };
	item.mask = TVIF_STATE;
	item.hItem = 参数_项目句柄;
	item.state = ~TVIS_BOLD;
	item.stateMask = TVIS_BOLD;
	return sendMsg(TVM_SETITEMW, 0, (LPARAM)&item) != 0;
}
bool DarkMoonUI::zyTreeView::是否选中(HTREEITEM 参数_项目句柄) {//返回指定项目检查框是否选中
	int 局部_状态 = (int)sendMsg(TVM_GETITEMSTATE, (WPARAM)参数_项目句柄, 0);
	return  ((局部_状态 & TVIS_STATEIMAGEMASK) << 12) == 2;
}
bool DarkMoonUI::zyTreeView::置检查框状态(HTREEITEM 参数_项目句柄, int 参数_状态) {//成功返回真，失败返回假。
	TVITEMEX item = { 0 };
	item.mask = TVIF_STATE;
	item.hItem = 参数_项目句柄;
	item.state = (参数_状态 + 1) >> 12;
	item.stateMask = TVIS_STATEIMAGEMASK;
	return sendMsg(TVM_SETITEMW, 0, (LPARAM)&item) != 0;
}
int DarkMoonUI::zyTreeView::取检查框状态(HTREEITEM 参数_项目句柄) {//1：选中，0：取消选中。
	TVITEMEX item = { 0 };
	item.mask = TVIF_STATE;
	item.hItem = 参数_项目句柄;
	item.stateMask = TVIS_STATEIMAGEMASK;
	if (sendMsg(TVM_GETITEMW, 0, (LPARAM)&item) == 0) {
		return 0;
	}
	return  ((item.state & TVIS_STATEIMAGEMASK) << 12) - 1;
}
int DarkMoonUI::zyTreeView::取所有选中项(std::vector<INT_PTR>& 参数_选中项数组) {//返回所有检查框选中的项目数量。
	int i = 0;
	bool 局部_完成= false;
	TVITEMEX item = { 0 };
	参数_选中项数组.resize(0);
	INT_PTR 局部_子项目 = sendMsg(TVM_GETNEXTITEM, TVGN_ROOT, 0);  // 取第一个根项目;
	item.mask = TVIF_STATE;
	while (局部_子项目 != 0) {
		i = i + 1;
		item.hItem = (HTREEITEM)局部_子项目;
		if (sendMsg(TVM_GETITEMW, 0, (LPARAM)&item) == 0) {
			return 0;
		}
		if (((item.state & TVIS_STATEIMAGEMASK) << 12) == 2) {  // 第一个索引是未选中，二个是选中{
			参数_选中项数组.push_back((INT_PTR)item.hItem);
		}
		INT_PTR 局部_数值 = 局部_子项目;
		局部_子项目 = sendMsg(TVM_GETNEXTITEM, TVGN_CHILD, 局部_子项目);  // 取第一个子项目;
		if (局部_子项目 == 0) {  // 找不到子项目，就找兄弟项目{
			局部_子项目 = sendMsg(TVM_GETNEXTITEM, TVGN_NEXT, 局部_数值);  // 取下一个兄弟项目;
			while (局部_子项目 == 0) { // 找不到兄弟项目，就返回到上一级;
				INT_PTR 局部_父项目 = sendMsg(TVM_GETNEXTITEM, TVGN_PARENT, 局部_数值);  // 取父项目;
				if (局部_父项目 == 0) {
					局部_完成 = true;
					break;
				}
				局部_数值 = 局部_父项目;
				局部_子项目 = sendMsg(TVM_GETNEXTITEM, TVGN_NEXT, 局部_数值);  // 取父的兄弟;
			}
		}
		if (局部_完成 == true) {
			break;
		}
	}
	return (int)参数_选中项数组.size();
}
bool DarkMoonUI::zyTreeView::排序子项回调(HTREEITEM 参数_项目句柄, void* 参数_排序子程序, int 参数_排序参数) {
	TVSORTCB tsb = { 0 };
	tsb.hParent = 参数_项目句柄;
	tsb.lpfnCompare = (PFNTVCOMPARE)参数_排序子程序;
	tsb.lParam = 参数_排序参数;
	return sendMsg(TVM_SORTCHILDRENCB, 0, (LPARAM)&tsb) != 0;
}
bool DarkMoonUI::zyTreeView::标志插入(HTREEITEM 参数_项目句柄, int 参数_插入位置 = 1) {//在一个项目的上面或下面插入一个标志。成功返回真，失败返回假。
	return sendMsg(TVM_SETINSERTMARK, 参数_插入位置, (LPARAM)参数_项目句柄) != 0;
}
void DarkMoonUI::zyTreeView::置图片组(zyLmageList& 参数_图片组, int 参数_类型)
{
	// 获取当前设置的图片组对象
	resObject* pImageList = nullptr;
	if (参数_类型 == TVSIL_NORMAL) {
		pImageList = reinterpret_cast<resObject*>(GetMember(L"pImageListNormal"));
	}
	else if (参数_类型 == TVSIL_STATE) {
		pImageList = reinterpret_cast<resObject*>(GetMember(L"pImageListState"));
	}
	if (pImageList != nullptr) {
		pImageList->release();
	}
	// 获取新图片组的对象并增加引用计数
	resObject* newImageList = 参数_图片组.getObject();
	newImageList->addRef();
	//IUnknown_AddRef (newImageList);
	// 设置新的图片组对象到成员变量中
	if (参数_类型 == TVSIL_NORMAL)
		SetMember(L"pImageListNormal", (LONG_PTR)newImageList);
	else if (参数_类型 == TVSIL_STATE)
		SetMember(L"pImageListState", (LONG_PTR)newImageList);
	// 发送消息设置树视图控件的图片组
	sendMsg(TVM_SETIMAGELIST, 参数_类型, reinterpret_cast<LPARAM>(参数_图片组.取句柄()));
}
DarkMoonUI::zyLmageList* DarkMoonUI::zyTreeView::取图片组(int 参数_类型) {
	// 定义类型映射表
	struct ImageListTypeMap {
		const wchar_t* name;
		int type;
	};
	static const ImageListTypeMap imageListTypes[] = {
		{ L"pImageListNormal", TVSIL_NORMAL },
		{ L"pImageListState",  TVSIL_STATE  }
	};

	// 查找匹配的类型
	const wchar_t* memberName = nullptr;
	for (size_t i = 0; i < sizeof(imageListTypes) / sizeof(ImageListTypeMap); ++i) {
		if (imageListTypes[i].type == 参数_类型) {
			memberName = imageListTypes[i].name;
			break;
		}
	}

	if (!memberName) return nullptr;

	// 返回已存在的图片组
	if (resObject* pExist = reinterpret_cast<resObject*>(GetMember(memberName))) {
		zyLmageList* pImageList = new zyLmageList();
		pImageList->setObject(pExist);
		return pImageList;
	}

	// 创建新图片组
	HIMAGELIST hImageList = reinterpret_cast<HIMAGELIST>(sendMsg(TVM_GETIMAGELIST, 参数_类型, 0));
	if (!hImageList) return nullptr;

	zyLmageList* pNewImageList = new zyLmageList();
	pNewImageList->置句柄(hImageList);
	pNewImageList->getObject()->addRef();
	SetMember(memberName, reinterpret_cast<LONG_PTR>(pNewImageList));

	return pNewImageList;
}
//DarkMoonUI::zyLmageList* DarkMoonUI::zyTreeView::取图片组(int 参数_类型)
//{
//	zyLmageList* ImageList = nullptr;
//	resObject* pImageList = nullptr;
//	if (参数_类型 == TVSIL_NORMAL)
//		pImageList = (resObject*)GetMember(L"pImageListNormal");
//	else if (参数_类型 == TVSIL_STATE)
//		pImageList = (resObject*)GetMember(L"pImageListState");
//	if (pImageList != nullptr) {
//		ImageList->setObject(pImageList);
//		return ImageList;
//	}
//	ImageList = new zyLmageList();
//	ImageList->置句柄((HIMAGELIST)sendMsg(TVM_GETIMAGELIST, 参数_类型, 0));
//	ImageList->getObject()->addRef();
//	//IUnknown_AddRef (pImageList);
//	if (参数_类型 == TVSIL_NORMAL)
//		SetMember(L"pImageListNormal", (LONG_PTR)ImageList);
//	else if (参数_类型 == TVSIL_STATE)
//		SetMember(L"pImageListState", (LONG_PTR)ImageList);
//	return ImageList;
//}
DarkMoonUI::zyLmageList DarkMoonUI::zyTreeView::创建拖放图片组(HTREEITEM 参数_项目句柄)
{
	zyLmageList iml;
	HIMAGELIST ImageList = (HIMAGELIST)sendMsg(TVM_CREATEDRAGIMAGE, 0, (LPARAM)参数_项目句柄);
	iml.置句柄((HIMAGELIST)ImageList);
	return iml;
}
INT_PTR DarkMoonUI::zyTreeView::取坐标项目(int 参数_横向坐标, int 参数_纵向坐标, int& 参数_位置信息) {//成功返回项目句柄，失败返回0。
	TVHITTESTINFO 局部_位置信息 = { 0 };
	局部_位置信息.pt.x = 参数_横向坐标;
	局部_位置信息.pt.y = 参数_纵向坐标;
	INT_PTR 局部_项目句柄 = sendMsg(TVM_HITTEST, 0, (LPARAM)&局部_位置信息);
	参数_位置信息 = 局部_位置信息.flags;
	return 局部_项目句柄;
}
int DarkMoonUI::zyTreeView::取子项数(HTREEITEM 参数_项目句柄) {//取出指定项目的子项目数。
	int 局部_数量 = 0;
	INT_PTR 局部_子项目 = sendMsg(TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)参数_项目句柄);
	while (局部_子项目 != 0) {
		局部_数量 = 局部_数量 + 1;
		局部_子项目 = sendMsg(TVM_GETNEXTITEM, TVGN_NEXT, 局部_子项目);
	}
	return 局部_数量;
}
int DarkMoonUI::zyTreeView::取所有子项目(HTREEITEM 参数_项目句柄, std::vector<HTREEITEM>& 参数_子项目句柄数组, bool 参数_递归) {
	HTREEITEM 局部_子项目;
	bool 局部_完成= false;
	参数_子项目句柄数组.resize(0);
	if (参数_递归) {
		局部_子项目 = (HTREEITEM)sendMsg(TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)参数_项目句柄);  // 取第一个子;
		while (局部_子项目 != 0) {
			参数_子项目句柄数组.push_back(局部_子项目);
			HTREEITEM 局部_历时句柄 = 局部_子项目;
			局部_子项目 = (HTREEITEM)sendMsg(TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)局部_子项目); // 取第一个子项目;
			if (局部_子项目 == 0) {  // 找不到子项目，就找兄弟项目{
				局部_子项目 = (HTREEITEM)sendMsg(TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)局部_历时句柄);  // 取下一个兄弟项目;
				while (局部_子项目 == 0) { // 找不到兄弟项目，就返回到上一级;
					HTREEITEM 局部_父项目 = (HTREEITEM)sendMsg(TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)局部_历时句柄);  // 取父项目;
					if (局部_父项目 == 参数_项目句柄) {
						局部_完成 = true;
						break;
					}
					局部_历时句柄 = 局部_父项目;
					局部_子项目 = (HTREEITEM)sendMsg(TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)局部_历时句柄); // 取父的兄弟;
				}
			}
			if (局部_完成 == true) {
				break;
			}
		}
	}
	else {
		局部_子项目 = (HTREEITEM)sendMsg(TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)参数_项目句柄);
		while (局部_子项目 != 0) {
			参数_子项目句柄数组.push_back(局部_子项目);
			局部_子项目 = (HTREEITEM)sendMsg(TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)局部_子项目);
		}
	}
	return (int)参数_子项目句柄数组.size();
}
std::wstring DarkMoonUI::zyTreeView::取结束编辑文本() {//在结束编辑事件中取出编辑后文本
	std::wstring 局部_返回值;
	HWND 局部_句柄 = (HWND)sendMsg(TVM_GETEDITCONTROL, 0, 0);
	int 局部_长度 = GetWindowTextLength(局部_句柄) * 2 + 2;
	局部_返回值.reserve(局部_长度);
	if (GetWindowText(局部_句柄, (LPWSTR)局部_返回值.c_str(), 局部_长度) == 0) {
		return L"";
	}
	return 局部_返回值;
}
DarkMoonUI::zyEditBox* DarkMoonUI::zyTreeView::取编辑框() {//当组合框风格为"组合框_允许编辑"时，获取其中的编辑框控件
	zyEditBox* pEdit = (zyEditBox*)GetMember(L"pEdit");
	if (pEdit != nullptr) {
		return pEdit;
	}
	HWND hwndItem = (HWND)sendMsg(TVM_GETEDITCONTROL, 0, 0);
	if (IsWindow(hwndItem) != 0) {
        pEdit = new zyEditBox();
		pEdit->_BindWindow(hwndItem);
		pEdit->getObject()->addRef();
		SetMember(L"pEdit", (LONG_PTR)pEdit);
	}
	return pEdit;
}
int DarkMoonUI::zyTreeView::项目高度(int 参数_高度) {//设置或获取项目高度。
	if (参数_高度 == NULL)
		return (int)sendMsg(TVM_GETITEMHEIGHT, 0, 0);
	return (int)sendMsg(TVM_SETITEMHEIGHT, 参数_高度, 0);
}
int DarkMoonUI::zyTreeView::缩进距离(int 参数_距离) {//设置或获取缩进距离。
	if (参数_距离 == NULL)
		return (int)sendMsg(TVM_GETINDENT, 0, 0);
	return (int)sendMsg(TVM_SETINDENT, 参数_距离, 0);
}
int DarkMoonUI::zyTreeView::文本色(int 参数_颜色值) {//设置或获取树型框文本颜色。
	if (参数_颜色值 == NULL) {
		return (int)sendMsg(TVM_GETTEXTCOLOR, 0, 0);
	}
	return (int)sendMsg(TVM_SETTEXTCOLOR, 0, 参数_颜色值);
}
int DarkMoonUI::zyTreeView::背景色(int 参数_颜色值) {//设置或获取树型框背景颜色。
	if (参数_颜色值 == NULL) {
		return (int)sendMsg(TVM_GETBKCOLOR, 0, 0);
	}
	return (int)sendMsg(TVM_SETBKCOLOR, 0, 参数_颜色值);
}
int DarkMoonUI::zyTreeView::连线色(int 参数_颜色值) {//设置或获取树型框连线颜色。
	if (参数_颜色值 == NULL) {
		return (int)sendMsg(TVM_GETLINECOLOR, 0, 0);
	}
	return (int)sendMsg(TVM_SETLINECOLOR, 0, 参数_颜色值);
}